package com.mxt.record.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mxt.common.vo.Result;
import com.mxt.data.mapper.DataMapper;
import com.mxt.devices.mapper.DevicesMapper;
import com.mxt.record.entity.Cord;
import com.mxt.record.mapper.CordMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author mxt
 * @since 2023-06-12
 */
@RestController
@CrossOrigin
@RequestMapping("/record")
public class CordController {

    @Autowired
    private CordMapper cordMapper;
    /*
    @Autowired 是 Spring 框架中的一个注解，它可以自动装配一个 Bean 对象，
    使我们无需手动创建该对象，从而方便了程序的开发
    。在这段代码中，CordMapper 是一个 MyBatis 的映射器接口，
    通过使用 @Autowired 注解，可以将该接口对应的实现类自动注入到当前类中
    ，从而方便我们在代码中使用该接口提供的方法。
    * */
    @Autowired
    private DevicesMapper devicesMapper;

    @Autowired
    private DataMapper dataMapper;


    @GetMapping
    public Result listRecord() {
        List<Cord> cords = cordMapper.selectList(null);
        return Result.success(cords);
    }

    @GetMapping("/page")
    public Result selectPerson(@RequestParam Integer pageNum, @RequestParam Integer pageSize){
        Page<Cord> page = new Page<>(pageNum,pageSize);
        Page<Cord> personPage = cordMapper.selectPage(page,null);
        List<Cord> list = personPage.getRecords();
        return Result.success(list);
    }


    @GetMapping("num")
    public Result getNum() {
        //QueryWrapper 是 MyBatis-Plus 框架提供的一个实用工具类，用于生成 SQL 查询语句的条件部分，可以帮助我们快速构建复杂的查询条件
        //QueryWrapper<Cord> 表示创建一个条件构造器对象，该对象用于构建 Cord 实体类对应的表中的查询条件。
        QueryWrapper<Cord> wrapper = new QueryWrapper<>();

        wrapper.select("statue");
        //cordMapper 是一个 MyBatis 的映射器接口
        //cordMapper 的 selectObjs 方法是用来执行查询操作的，该方法将传入的查询条件 wrapper 转换为 SQL 查询语句，并执行查询操作，返回一个包含所有结果的列表
        List<Object> objList = cordMapper.selectObjs(wrapper); // 查询结果为Object类型的列表
        List<String> result = new ArrayList<>();
        for (Object obj : objList) {
            result.add(obj.toString()); // 将Object类型转换为String类型，并添加到结果列表中
        }
        Integer[] countArray = new Integer[]{0, 0, 0, 0};

        for (String str : result) {
            if (str.equals("已处理")) {
                countArray[0]++;
            } else if (str.equals("未处理")) {
                countArray[1]++;
            } else if (str.equals("已忽略")) {
                countArray[2]++;
            }
        }
        countArray[3] = countArray[0] + countArray[1] + countArray[2];
        System.out.println(countArray);

        return Result.success(countArray);
    }

    @GetMapping("/search")
    public Result selectRecord(Integer input, String value, String startDate, String endDate) {
        QueryWrapper<Cord> wrapper = new QueryWrapper<>();
        if (input != null) {
            wrapper.eq("idrecord", input);
        }
        if (value != null) {
            wrapper.eq("statue", value);
        }
        if (startDate != null && endDate != null) {
            LocalDate start = LocalDate.parse(startDate.substring(0, 10));
            LocalDate end = LocalDate.parse(endDate.substring(0, 10));
            wrapper.ge("begintime", start);
            wrapper.le("endtime", end);
        }
        List<Cord> cords = cordMapper.selectList(wrapper);
        return Result.success(cords);
    }


    @PostMapping("/update")
    public Result updateRecordById(@RequestBody Cord cord) {
        cordMapper.updateById(cord);
        return Result.success();
    }

    @GetMapping("api")
    public Result getData() {
        List<LocalDateTime> dateTimes = devicesMapper.getDate();
        ArrayList<LocalDate> dates = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        for (LocalDateTime dateTime : dateTimes) {
            LocalDate date = LocalDate.parse(dateTime.format(formatter), formatter);
            dates.add(date);
        }
        LocalDate currentDate = LocalDate.now();
        System.out.println(currentDate);
        long count = dates.stream()
                .filter(date -> date.equals(currentDate))
                .count();
        System.out.println(count);
        Integer[] countArray = new Integer[]{0, 0, 0};
        countArray[0] = dates.size();
        countArray[1] = (int) count;
        countArray[2] = countArray[0]-countArray[1];
        return Result.success(countArray);
    }

    @GetMapping("api1")
    public Result getMonth() {
        List<LocalDateTime> dateTimes = dataMapper.getTime();
        List<String> monthList = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        for (LocalDateTime dateTime : dateTimes) {
            String month = dateTime.format(formatter);
            if (!monthList.contains(month)) {
                monthList.add(month);
            }
        }
        Collections.sort(monthList);
        return Result.success(monthList);
    }

    @GetMapping("api3")
    public Result getCount() {
        List<LocalDateTime> dateTimes = dataMapper.getTime();

        Map<String, Integer> countMap = new HashMap<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");

        LocalDateTime now = LocalDateTime.now();
    //当前时间七个月前的时间
        LocalDateTime sixMonthsAgo = now.minusMonths(7);
//遍历 dateTimes 列表，统计最近七个月内的记录数量，并将统计结果存储在一个 Map<String, Integer> 对象 countMap 中。

        for (LocalDateTime dateTime : dateTimes) {
            if (dateTime.isAfter(sixMonthsAgo) && dateTime.isBefore(now.plusMonths(1))) {
                String month = dateTime.format(formatter);
               /*
               使用 put 方法向 countMap 中添加或更新一个键值对，
               其中键是月份的字符串表示，值是该月份的新的记录数量。
              如果 countMap 中已经存在该月份的统计结果
               ，则该月份的记录数量会被更新，
               否则会将该月份的记录数量设置为 1。
               */
                countMap.put(month, countMap.getOrDefault(month, 0) + 1);
            }
        }
    /*
     for 循环遍历最近七个月的月份，对于每个月份
     ，首先使用 minusMonths 方法从当前时间对象 now
      中减去相应的月份数，得到一个新的时间对象 monthTime，
      表示该月份的时间。然后使用 DateTimeFormatter
     类将该时间对象格式化成字符串类型的月份 month。
    * */
        List<Map<String, Integer>> countList = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            LocalDateTime monthTime = now.minusMonths(i);
            String month = monthTime.format(formatter);
            /*
            使用 getOrDefault 方法从 countMap
            中获取该月份的记录数量统计结果，
            如果 countMap 中不存在该键，则使用默认值 0
       */
            Integer count = countMap.getOrDefault(month, 0);
            Map<String, Integer> map = new HashMap<>();
            map.put(month, count);
            countList.add(map);
        }
        return Result.success(countList);
    }

    @GetMapping("api2")
    public Result getRecordNum() {
        List<LocalDate> dateTimes = cordMapper.getRecord();

// 获取当前月和前六个月的月份字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
      //mapToObj
        //使用 mapToObj 方法将每个整数转换成一个 LocalDate 类型的日期对象
        // ，这个日期对象表示当前时间往前推 i 个月的日期
        //使用 collect 方法将转换后的字符串收集到一个列表中，这个列表就是 months
        // 变量。这个列表中包含了当前时间往前推 6 个月的月份信息
        List<String> months = IntStream.rangeClosed(0, 6)
                .mapToObj(i -> LocalDate.now().minusMonths(i))
                .map(date -> date.format(formatter))
                .collect(Collectors.toList());

// 统计每个月份的个数
        //使用 stream() 方法将 dateTimes 列表转换成一个流
        // filter 方法过滤掉不在指定月份范围内的日期
        //使用 groupingBy 方法对符合条件的日期进行分组，
        // 按照月份进行分组，得到一个以月份为键、计数为值的 Map 对象。
       // date -> date.format(formatter) 表示按照日期格式化后的字符串进行分组
        //Collectors.counting() 表示对分组后每组的元素进行计数。
        Map<String, Long> countMap = dateTimes.stream()
                .filter(date -> months.contains(date.format(formatter)))
                .collect(Collectors.groupingBy(date -> date.format(formatter), Collectors.counting()));

// 构造结果
        //对于每个月份，创建一个新的 HashMap 对象 map，并从 countMap 中获取该月份的统计结果，将统计结果存储在 map 对象中。
        // 如果在 countMap 中不存在该月份的统计结果，则将该月份的统计结果设置为 0
        List<Map<String, Long>> resultList = new ArrayList<>();
        for (String month : months) {
            Map<String, Long> map = new HashMap<>();
            map.put(month, countMap.getOrDefault(month, 0L));
            resultList.add(map);
        }

        return Result.success(resultList);
    }


}
